package own.stu.jobgib.playown.vediodown.common.service;

import com.google.gson.Gson;
import org.asynchttpclient.AsyncHttpClient;
import org.redisson.api.RQueue;
import org.redisson.api.RSet;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import own.stu.jobgib.playown.vediodown.common.config.DefaultConfig;
import own.stu.jobgib.playown.vediodown.common.model.SimpleMediaItem;

import java.util.List;

public class CacheItemService {

    protected static Logger logger = LoggerFactory.getLogger(CacheItemService.class);

    protected String DEFAULT_PLATFORM;
    protected RedissonClient redisson;

    protected AsyncHttpClient client;
    protected Gson gson;

    public CacheItemService(DefaultConfig cfg) {
        DEFAULT_PLATFORM = cfg.getPlatform();
        redisson = cfg.getRedisson();
        client = cfg.getClient();
        gson = cfg.getGson();
    }

    public void cacheMediaItemInfo(String userId, List<SimpleMediaItem> mediaList) {
        RQueue<SimpleMediaItem> queue = redisson.getQueue(getMediaQueue(userId));

        for (SimpleMediaItem item : mediaList) {
            cacheMediaItemInfo(queue, userId, item);
        }
    }

    public boolean cacheMediaItemInfo(RQueue<SimpleMediaItem> queue, String userId, SimpleMediaItem item) {

        // todo can replace by lua script
        if (checkCached(item.getBvId(), userId)) {
            return false;
        }
        long curId = getNextIdxByUserId(userId + "");
        item.setId(curId);
        queue.add(item);

        cachedSet(item.getBvId(), userId);
        return true;
    }

    // Qeuee
    protected String getMediaQueue(String userId) {
        return DEFAULT_PLATFORM + ":" + userId;
    }

    // Set
    private String itemCacheSetName(String userId) {
        return DEFAULT_PLATFORM + ":" + "set-" + userId;
    }

    private boolean checkCached(String bvId, String userId) {
        RSet<String> set = redisson.getSet(itemCacheSetName(userId));
        return set.contains(bvId);
    }

    private boolean cachedSet(String bvId, String userId) {
        RSet<String> set = redisson.getSet(itemCacheSetName(userId));
        return set.add(bvId);
    }

    // string: id
    private long getNextIdxByUserId(String userId) {
        long curId = getNextIdxByUserId(userId, DEFAULT_PLATFORM);
        return curId;
    }

    private long getNextIdxByUserId(String id, String platForm) {
        String strId = String.format(id_format, platForm, id);
        return redisson.getAtomicLong(strId).incrementAndGet();
    }

    public void setInitIdx(String id, long initIdx) {
        String strId = String.format(id_format, DEFAULT_PLATFORM, id);
        redisson.getAtomicLong(strId).set(initIdx);
    }

    private String id_format = "id:%s:%s";
}
